package main

import (
	"fmt"
	"sync"
	"time"
)

// 一个简单的并发任务
func sayHello() {
	time.Sleep(1 * time.Second)
	fmt.Println("Hello from goroutine!")
}

func testGoRoutine() {
	go sayHello() // 创建一个 goroutine
	fmt.Println("Hello from main!")
	time.Sleep(2 * time.Second) // 等待 goroutine 执行完毕
}

func testChannelWithoutBuf() {
	ch := make(chan string) // 创建一个无缓冲 channel

	// 启动 goroutine 发送数据
	go func() {
		ch <- "Hello from goroutine!" // 向 channel 发送数据
	}()

	// 接收数据
	msg := <-ch
	fmt.Println(msg) // 输出: Hello from goroutine!
}

func testChannelWithBuf() {
	ch := make(chan string, 2) // 创建一个缓冲区大小为 2 的 channel

	ch <- "Hello"
	ch <- "World" // 向 channel 发送两个消息

	fmt.Println(<-ch) // 输出: Hello
	fmt.Println(<-ch) // 输出: World
}

func testSelect() {
	ch1 := make(chan string)
	ch2 := make(chan string)

	go func() {
		time.Sleep(1 * time.Second)
		ch1 <- "Message from ch1"
	}()

	go func() {
		time.Sleep(2 * time.Second)
		ch2 <- "Message from ch2"
	}()

	// 使用 select 语句监听多个 channel
	select {
	case msg1 := <-ch1:
		fmt.Println("Received:", msg1)
	case msg2 := <-ch2:
		fmt.Println("Received:", msg2)
	}
}

var counter int
var mutex sync.Mutex

func increment() {
	mutex.Lock() // 加锁
	counter++
	mutex.Unlock() // 解锁
}

func testMutex() {
	var wg sync.WaitGroup

	// 启动多个 goroutine 进行并发操作
	for i := 0; i < 1000; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			increment()
		}()
	}

	wg.Wait() // 等待所有 goroutine 执行完毕
	fmt.Println("Final counter:", counter)
}

var rwMutex sync.RWMutex

func read() int {
	rwMutex.RLock() // 读锁
	defer rwMutex.RUnlock()
	return counter
}

func write() {
	rwMutex.Lock() // 写锁
	counter++
	rwMutex.Unlock()
}

func testRWMutex() {
	var wg sync.WaitGroup

	// 启动多个 goroutine 进行读写操作
	for i := 0; i < 1000; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			write()
		}()
	}

	for i := 0; i < 1000; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			read()
		}()
	}

	wg.Wait()
	fmt.Println("Final counter:", counter)
}

func task(wg *sync.WaitGroup) {
	defer wg.Done() // 执行完毕时调用 Done
	fmt.Println("Task completed")
}

func testWaitGroup() {
	var wg sync.WaitGroup

	// 启动多个 goroutine
	for i := 0; i < 5; i++ {
		wg.Add(1) // 增加等待的 goroutine 数量
		go task(&wg)
	}

	wg.Wait() // 等待所有 goroutine 执行完毕
	fmt.Println("All tasks completed")
}

func main() {
	// testGoRoutine()
	// testChannelWithoutBuf()
	// testChannelWithBuf()
	// testSelect()
	// testMutex()
	testRWMutex()
}
